import Axios from 'axios'
import apiName from '../data'
import headersConfig from '../config/axios.config'
import {
    objectFormatKeysJoinUrl,
    objectFormatJoinUrl,
    downloadFile,
    fileNameFromHeader,
    formatFormData,
    catchAjaxResolve,
    catchAjaxReject
} from './axiosExpand'

// 常量定义（避免硬编码）
const STORAGE_KEYS = {
    TOKEN: 'web_token',
    USER_INFO: 'userInfo'
}

// 请求拦截器（添加配置保护）
Axios.interceptors.request.use(config => {
    if (!config.headers) config.headers = {}
    config.headers = {
        ...headersConfig.headers,
        ...config.headers,
        ...(localStorage.getItem(STORAGE_KEYS.TOKEN) ? { token: localStorage.getItem(STORAGE_KEYS.TOKEN) } : {})
    }
    if (config.method === 'post' && !config.headers['Content-Type']) {
        config.headers['Content-Type'] = 'application/json'
    }
    return config
}, error => {
    console.error('Request interceptor error:', error)
    return Promise.reject(error)
})

// 响应拦截器（添加错误日志）
Axios.interceptors.response.use(
    response => {
        try {
            return catchAjaxResolve(response)
        } catch (e) {
            console.error('Response interceptor processing error:', e)
            return Promise.reject(e)
        }
    },
    error => {
        console.error('Response interceptor error:', error)
        return catchAjaxReject(error)
    }
)

class Ajax {
    // 私有方法（实际运行时仍可访问，但通过命名约定表明私有性）
    _processData(method, url, data = {}, param = {}) {
        // 参数校验
        if (typeof url !== 'string') {
            return Promise.reject(new Error('URL must be a string'))
        }

        method = method.toLowerCase()

        // 下载处理
        if (method === 'get' && param.down) {
            try {
                this._handleDownload(url, data.fileName || data.title)
                return Promise.resolve(true)
            } catch (e) {
                return Promise.reject(new Error(`Download failed: ${e.message}`))
            }
        }

        // 数据处理
        let processedData = data
        let processedUrl = url

        if (data?.bodyParam) {
            processedData = this._deepClone(data.bodyParam)
        } else if (param.value) {
            processedUrl = method === 'post'
                ? objectFormatJoinUrl(data, url)
                : objectFormatKeysJoinUrl(data, url)
            processedData = method === 'get' ? null : data
        }

        // 特殊接口处理
        if (param.interFaceType === 'all') {
            if (!data.url) {
                return Promise.reject(new Error('Missing required field: url'))
            }
            processedUrl = fileNameFromHeader(data.url)
            processedData = formatFormData(data)
        }

        // 随机参数防缓存
        if (param.random) {
            processedUrl += (processedUrl.includes('?') ? '&' : '?') + 'time=' + Math.random()
        }

        // 发送请求
        try {
            return Axios({
                method,
                url: processedUrl,
                data: processedData,
                validateStatus: status => status >= 200 && status < 300
            })
        } catch (e) {
            return Promise.reject(new Error(`Request failed: ${e.message}`))
        }
    }

    _handleDownload(url, fileName) {
        if (!url) throw new Error('Download URL is required')

        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest()
            xhr.open('GET', url, true)
            xhr.responseType = 'blob'

            xhr.onload = () => {
                if (xhr.status === 200) {
                    try {
                        const finalFileName = fileName || fileNameFromHeader(xhr.responseURL, 1) || 'download'
                        downloadFile(finalFileName, xhr.response)
                        resolve(true)
                    } catch (e) {
                        reject(e)
                    }
                } else {
                    reject(new Error(`Download failed with status ${xhr.status}`))
                }
            }

            xhr.onerror = () => reject(new Error('Download request failed'))
            xhr.send()
        })
    }

    _deepClone(obj) {
        try {
            return JSON.parse(JSON.stringify(obj))
        } catch (e) {
            console.error('Deep clone failed:', e)
            return {}
        }
    }

    // 公共方法
    Post(url, data, param) { return this._processData('post', url, data, param) }
    Delete(url, data, param) { return this._processData('delete', url, data, param) }
    Put(url, data, param) { return this._processData('put', url, data, param) }
    Get(url, data, param) { return this._processData('get', url, data, param) }
}

export default function Fetch(name, data = {}) {
    // 参数校验
    if (!apiName[name]) {
        return Promise.reject(new Error(`API config '${name}' not found`))
    }
    // 校验URL格式
    const apiConfig = apiName[name]
    if (!apiConfig.url || typeof apiConfig.url !== 'string') {
        return Promise.reject(new Error(`接口 ${name} 的URL配置无效`))
    }

    const { headers, method, url } = apiName[name]

    // 合并headers
    if (headers) {
        headersConfig.headers = {
            ...headersConfig.headers,
            ...headers
        }
    }

    // 方法校验
    const httpMethod = method?.toLowerCase()
    if (!['get', 'post', 'put', 'delete'].includes(httpMethod)) {
        return Promise.reject(new Error(`Invalid HTTP method: ${method}`))
    }

    // URL校验
    if (!url) {
        return Promise.reject(new Error('API URL is required'))
    }

    try {
        return new Ajax()[httpMethod](
            headersConfig.baseURL + url,
            data,
            apiName[name]
        )
    } catch (e) {
        return Promise.reject(new Error(`Request initialization failed: ${e.message}`))
    }
}